home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 134_01.zip / GENREL.C < prev    next >
Text File  |  1993-06-12  |  6KB  |  170 lines

  1. /*    Program to generate a relocation directory in a .CRL    */
  2.  
  3. /*    This code is in the public domain    */
  4.  
  5. /*    The following program is intended for applications which need to
  6.     move code around at runtime in a `C' program.  It is called by:
  7.  
  8.     genrel input-crl-file function-name output-crl-file reloc-fn-name
  9.  
  10.     It reads input-crl-file, looking for a function called function-name.
  11.     This function may not reference any external functions.  If it finds
  12.     the function, it copies the relocation information associated with
  13.     it on the .CRL file into memory.  It then creates a new .CRL file
  14.     called output-crl-file.  This file will have the single function,
  15.     reloc-fn-name, which returns a pointer to the relocation data.
  16.  
  17.     An example of how the resulting function might be used is:
  18.  
  19. union ptf {
  20.     int (*f) ();
  21.     char *b;
  22.     unsigned *w;
  23.     };        /* Define 'pointer-to-function' */
  24.  
  25. move_fn (to, from, size, reloc) 
  26.     union ptf to;        /* Place in memory to put the new function */
  27.     union ptf from;        /* Place in memory where function is now */
  28.     unsigned size;        /* Size of the function in bytes */
  29.     union ptf reloc;        /* Relocation function built by GENREL */
  30.     {
  31.     unsigned diff;        /* Difference in the loading origins */
  32.     unsigned * reltab;    /* Relocation table */
  33.     unsigned nrelocs;    /* Number of relocation words */
  34.     union ptf relptr;    /* Pointer to word being relocated */
  35.  
  36.     movmem (from, to, size);    /* Move the function */
  37.  
  38.     diff = to - from;        /* Find out the relocation offset */
  39.     reltab = (*reloc.f) ();        /* Get the relocation data */
  40.     nrelocs = *reltab++;        /* Get the relocation count */
  41.  
  42.     while (nrelocs--) {        /* Count relocation entries */
  43.         relptr = to.b + *reltab++; /* Get a relocation entry */
  44.         *relptr.w += diff;    /* Add offset to relocated word */
  45.         }
  46.     }
  47.  
  48. ******************************************************************************/
  49.  
  50. #include "bdscio.h"
  51.  
  52. /*    Externals for the package    */
  53.  
  54. char crlfile [134];        /* CRL file being read or written via CHARIO */
  55. char crldir [512];        /* Function directory from .CRL file */
  56. union {
  57.     unsigned *w;
  58.     char *b;
  59.     } crlptr;        /* Pointer to current byte in crldir */
  60. char fname [9];            /* Current function name */
  61. char * namptr;            /* Pointer to current byte of fname */
  62. unsigned * reloctab;        /* Relocation table for the new .CRL file */
  63. int nrelocs;            /* Number of relocation bytes */
  64. int seekad;            /* Seek address in current file */
  65. unsigned ending;        /* Length of current file */
  66. unsigned i;            /* Working word */
  67. char c;                /* Working byte */
  68.  
  69. main (argc, argv)
  70.     int argc;
  71.     char ** argv;
  72.     {
  73.     if (argc != 5) {
  74.         printf ("Syntax: genrel infile function outfile relfunct\n");
  75.         exit ();
  76.         }
  77.  
  78.     if (copen (crlfile, argv[1], 0) == ERROR) {
  79.         printf ("Can't open %s: %s.\n", argv[1], errmsg (errno ()));
  80.         exit ();
  81.         }
  82.  
  83.     if (cread (crlfile, crldir, 512) < 512) {
  84.         printf ("Can't read CRL directory from %s: %s\n",
  85.                 argv [1], errmsg (errno ()));
  86.         exit ();
  87.         }
  88.  
  89.     crlptr.b = &crldir;        /* Initialize scan pointer */
  90.  
  91.     for (;;) {
  92.         if (*crlptr.b == 0x80) {    /* Didn't find the function */
  93.             printf ("Can't locate %s on %s\n", argv[2], argv[1]);
  94.             exit ();
  95.             }
  96.         namptr = &fname;
  97.         while ((*crlptr.b & 0x80) == 0) *namptr++ = *crlptr.b++;
  98.         *namptr++ = *crlptr.b++ & 0x7F;
  99.         *namptr++ = 0;            /* Scan function name */
  100.  
  101.         if (!strcmp (fname, argv[2])) break;  /* Found the function */
  102.         ++crlptr.w;        /* No match; skip seek address */
  103.         }
  104.  
  105.     seekad = *crlptr.w;        /* Find the function's external dir */
  106.  
  107.     cseek (crlfile, seekad, 0);    /* Seek to it */
  108.     cread (crlfile, &c, 1);        /* Read the first byte of ext dir */
  109.     if (c) {
  110.         printf ("Function %s on %s has externals and can't be moved\n",
  111.             fname, argv [1]);
  112.         exit ();
  113.         }
  114.     
  115.     cread (crlfile, &seekad, 2);    /* Now read the size of function body*/
  116.     cseek (crlfile, seekad, 1);    /* Seek around it */
  117.  
  118.     cread (crlfile, &nrelocs, 2);    /* Read relocation item count */
  119.     if ((reloctab = alloc (2*nrelocs)) == NULL) {
  120.         printf ("Can't find enough memory for reloctab.\n");
  121.         exit ();
  122.         }
  123.     cread (crlfile, reloctab, 2*nrelocs);    /* Read relocation data */
  124.     cclose (crlfile);        /* Done with input file */
  125.  
  126.     if (ccreat (crlfile, argv [3]) == ERROR) {
  127.         printf ("Can't create output file %s: %s.", argv[3],
  128.                     errmsg (errno ()));
  129.         exit ();
  130.         }
  131.  
  132.     crlptr.b = &crldir;
  133.     i = 0;
  134.     namptr = argv [4];
  135.     while (*crlptr.b++ = *namptr++) ++i;
  136.     crlptr.b [-2] |= 0x80;        /* Build output CRL directory */
  137.     cwrite (crlfile, crldir, i);
  138.     seekad = 0x0205;
  139.     cwrite (crlfile, &seekad, 2);  i += 2;
  140.     c=0x80;
  141.     cwrite (crlfile, &c, 1); ++i;
  142.     ending = seekad + 2*nrelocs + 13;
  143.     cwrite (crlfile, &ending, 2); i+=2;
  144.     c=0;
  145.     while (i < seekad) {
  146.         cwrite (crlfile, &c, 1);
  147.         ++i;
  148.         }
  149.     cwrite (crlfile, &c, 1);    /* Write external directory terminate*/
  150.     seekad = 2*nrelocs+6;
  151.     cwrite (crlfile, &seekad, 2);    /* Write function body size */
  152.     c=0x21;
  153.     cwrite (crlfile, &c, 1);    /* Write $$$LXI H, table */
  154.     i=4;
  155.     cwrite (crlfile, &i, 2);
  156.     c=0xC9;                /* Write $$$RET */
  157.     cwrite (crlfile, &c, 1);
  158.     cwrite (crlfile, &nrelocs, 2);    /* Write item count */
  159.     cwrite (crlfile, reloctab, 2*nrelocs);    /* Write relocation items */
  160.     i=1;
  161.     cwrite (crlfile, &i, 2);    /* Write real relocation count of 1 */
  162.     cwrite (crlfile, &i, 2);    /* Write real relocation item */
  163.     cflush (crlfile);
  164.     cclose (crlfile);
  165.     }
  166. 
  167.     i = 0;
  168.     namptr = argv [4];
  169.     while (*crlptr.b++ = *namptr++) ++i;
  170.     crlptr.b [-2] |= 0x80;        /* Build output